﻿using Microsoft.Kinect;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Threading.Tasks;

namespace DetectingKinectSencor
{
    /// <summary>
    /// The following process is used to save each frame
    /// Write the header (KinectRecordOptions.Skeletons).
    /// Compute the delta from the current time to the reference time and write it.
    /// Write the floor clip plane.
    /// Write the frame number.
    /// Serialize the skeletons array.
    /// 
    /// The following class was provided by the book 
    /// Microsoft.Press.Programming.with.the.Kinect.for.Windows.Software.Development.Kit.Sep.2012
    /// </summary>

    class RecordSkeletonStream
    {
        private bool DEBUGon = MainWindow.DEBUGrecordSkeltonStream;

        DateTime referenceTime;
        readonly BinaryWriter writer;
            
       /// <summary>
       /// Constuctor of RecordSkeletonStream
       /// </summary>
       /// <param name="writer"></param>
        internal RecordSkeletonStream(BinaryWriter writer)
        {
            this.writer = writer;
            referenceTime = DateTime.Now;
        }

        /// <summary>
        /// Method thad records the skeleton stream
        /// </summary>
        /// <param name="frame"></param>
        public void Record(SkeletonFrame frame)
        {
            // Write the hdeader, this is importat to distinguish between the three different streams
            // (at the end one file which includes the three streams)
            writer.Write((int)DetectingKinectSencor.RecordStreams.KinectRecordOptions.Skeletons);

            // Writing the data
            // Timespan is important, because a reference time is needed. Each recorder must keep a reference time
            // variable and add it to the saved stream to allow the player to reproduce the data at the same frequency
            TimeSpan timeSpan = DateTime.Now.Subtract(referenceTime);

            if (DEBUGon)
                Console.WriteLine("skeleton: Record: timeSpan: " + timeSpan.TotalMilliseconds);

            referenceTime = DateTime.Now;

            if (DEBUGon)
                Console.WriteLine("skeleton: Record: referenceTime: " + referenceTime.ToLongTimeString());

            writer.Write((long)timeSpan.TotalMilliseconds);
            
            writer.Write(frame.FloorClipPlane.Item1);
            writer.Write(frame.FloorClipPlane.Item2);
            writer.Write(frame.FloorClipPlane.Item3);
            writer.Write(frame.FloorClipPlane.Item4);

            writer.Write(frame.FrameNumber);
            if (DEBUGon)
                Console.WriteLine("skeleton: Record: FrameNumber: " + frame.FrameNumber);

            // Get all the skeletons which are tracked
            Skeleton[] skeletons = frame.GetSkeletons();

            // Serializes a object into a binary format
            BinaryFormatter formatter = new BinaryFormatter();
            formatter.Serialize(writer.BaseStream, skeletons);

        }
    }
}
